﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using ImageTools;
using Kiva7.Transitions;
using Kiva7.Utilities;
using Microsoft.Phone.Controls;
using System.Windows.Media;
using Kiva7.Settings;

namespace Kiva7.Controls
{
    public class BasePhoneApplicationPage : PhonePage, IImageSourceCache
    {
        public BasePhoneApplicationPage()
        {
            _ImageSourceCache = new ImageSourceCache(this);

            Loaded += BasePhoneApplicationPageLoaded;

            Projection = new PlaneProjection
                {
                    CenterOfRotationX = 0,
                    LocalOffsetX = 0,
                    RotationY = -120
            };

        }

        void BasePhoneApplicationPageLoaded(object sender, RoutedEventArgs e)
        {
            _goingBack = false;
            if (BindableApplicationBar != null
                && BindableApplicationBar.Buttons.Count == 0
                && BindableApplicationBar.MenuItems.Count == 0)
            {
                CreateApplicationBar();
            }

            DoNavigateBackTransition();
        }

        #region ApplicationBar

        protected virtual void CreateApplicationBar()
        {


        }

        protected BindableApplicationBarButton AddBarButton(string buttonText, string imageUrl, EventHandler handler)
        {
            if (BindableApplicationBar != null)
            {
                BindableApplicationBarButton appBarButton = new BindableApplicationBarButton()
                                                                { 
                                                                    IconUri =  new Uri(imageUrl, UriKind.Relative),
                                                                    Text = buttonText
                                                                };
                appBarButton.Click += handler;
                BindableApplicationBar.Buttons.Add(appBarButton);
                return appBarButton;
            }
            return null;
        }

        protected BindableApplicationBarMenuItem AddBarMenuItem(string buttonText, EventHandler handler)
        {
            if (BindableApplicationBar != null)
            {
                BindableApplicationBarMenuItem item = new BindableApplicationBarMenuItem { Text = buttonText };
                item.Click += handler;
                BindableApplicationBar.MenuItems.Add(item);
                return item;
            }
            return null;
        }

        public BindableApplicationBar BindableApplicationBar
        {
            get;
            set;
        }


        protected virtual void CreateStandardControls()
        {
            
        }

#endregion

        #region Navigation

        private bool _isPostback;
        public bool IsPostback
        {
            get
            {
                return _isPostback;
            }
        }

        private void DoNavigateBackTransition()
        {
            TurnTransition stile = new TurnTransition();

            if (!IsPostback)
            {
                stile.Mode = TurnTransitionMode.Forward;
            }
            else
            {
                stile.Mode = TurnTransitionMode.Backward;
            }

            ITransition transition = stile.GetTransition(this);
            transition.Begin();
        }

        private bool _goingBack;
        protected override void OnBackKeyPress(CancelEventArgs e)
        {
            if (NavigationService.CanGoBack
                && !_goingBack)
            {
                _goingBack = true;
                e.Cancel = true;
                //base.OnBackKeyPress(e);
                _navigateUri = null;
                _isPostback = true;
                NavigateTransition stile = new NavigateTransition
                    {
                        Mode = NavigateTransitionMode.Backward
                    };
                ITransition transition = stile.GetTransition(this);
                transition.Begin();
            }
        }

        public void GoPageBack()
        {
            DoBackKeyPress();
        }

        private void DoBackKeyPress()
        {
            base.OnBackKeyPress(new CancelEventArgs());
            NavigationService.GoBack();
        }

        internal void DoNavigate(Uri uri)
        {
            _navigateUri = uri;
            _isPostback = true;
            NavigateTransition stile = new NavigateTransition
                {
                    Mode = NavigateTransitionMode.Forward
                };

            ITransition transition = stile.GetTransition(this);
            transition.Begin();
        }

        private Uri _navigateUri;

        public static readonly DependencyProperty TriggerNavigationProperty =
            DependencyPropertyExt.Register<BasePhoneApplicationPage, object>(x => x.TriggerNavigation,
                                                                             new PropertyMetadata(null,
                                                                                                  TriggerNavigationChanged));

        public object TriggerNavigation
        {
            get 
            { 
                return GetValue(TriggerNavigationProperty); 
            }
            set
            {
                SetValue(TriggerNavigationProperty, value);
            }
        }

        private static void TriggerNavigationChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (args.NewValue != null)
            {
                BasePhoneApplicationPage page = (BasePhoneApplicationPage) obj;
                if (page._navigateUri != null)
                {
                    page.NavigationService.Navigate(page._navigateUri);
                    page._navigateUri = null;
                }
                else
                {
                    page.DoBackKeyPress();
                }
            }
        }

#endregion

        #region BackgroundImage

        public DataClasses.Image ImageData
        {
            get { return (Kiva7.DataClasses.Image)GetValue(ImageProperty); }
            set { SetValue(ImageProperty, value); }
        }

        public static readonly DependencyProperty ImageProperty =
                        DependencyPropertyExt.Register<BasePhoneApplicationPage, Kiva7.DataClasses.Image>(x => x.ImageData,
                                                                             new PropertyMetadata(EntityChanged));

        private static void EntityChanged(DependencyObject d,
                                     DependencyPropertyChangedEventArgs e)
        {
            BasePhoneApplicationPage pc = d as BasePhoneApplicationPage;
            if (pc != null)
            {
                pc.EntityChanged();
            }

        }

        public Uri CreateImageUri()
        {
            
            return Kiva7.DataClasses.Image.CreateImageUri(ImageData.Id, "W120H200");
        }

        public string GetImageDirectoryName()
        {
            return "BackgroundImagesGrey";
        }

        public string GetImagePath()
        {
            if (this.ImageData != null)
            {
                return System.IO.Path.Combine(GetImageDirectoryName(), this.ImageData.Id + ".JPG");
            }
            return null;
        }

        protected void EntityChanged()
        {
            if (!AppSettings.Current.ShowBackgroundImage)
            {
                return;
            }
            Panel panel = Content as Panel;
            if (this.ImageData == null)
            {
                panel.Background = null;
                return;
            }

            _imageBrush = new ImageBrush();
            _imageBrush.ImageOpened += ImageOpened;

            //ImageSourceConverter isc = new ImageSourceConverter();

            //_imageBrush.ImageSource = isc.ConvertFrom(CreateImageUri()) as ImageSource;
            _imageBrush.Opacity = 0;

            if (panel != null)
            {
                panel.Background = _imageBrush;
            }
            Control control = Content as Control;
            if (control != null)
            {
                control.Background = _imageBrush;
            }

            _ImageSourceCache.EntityChanged();
        }

        private readonly ImageSourceCache _ImageSourceCache;


        protected void ImageOpened(object sender, RoutedEventArgs e)
        {
            _ImageSourceCache.ImageOpened(sender, e);

        }

        public virtual bool ApplyFilter(ref ExtendedImage extendedImage)
        {
            IImageFilter filter = GetFilter();
            if (filter != null)
            {
                ExtendedImage temp = extendedImage.Clone();

                filter.Apply(temp, extendedImage, temp.Bounds);

                extendedImage = temp;
                return true;
            }

            return false;
        }

        protected virtual IImageFilter GetFilter()
        {
            return new ImageTools.Filtering.GrayscaleBT709();

            //return new ImageTools.Filtering.Colored(new Color() { R = 116, G = 180, B = 70 });

            //return new ImageTools.Filtering.Colored(new Color() { R = 75, G = 145, B = 35 });
        }

        private ImageBrush _imageBrush;
        public ImageSource Source
        {
            get
            {
                return _imageBrush.ImageSource;
            }
            set
            {
                _imageBrush.ImageSource = value;
            }
        }

        public void SetOpacity()
        {
            _imageBrush.Opacity = 0.3;
        }

        #endregion

    }
}
